<template>
  <div class="depart-page">

    <!-- 组织树 -->
    <div class="depart-tree">
      <div class="depart-title">
        <span>组织管理</span>
        <div>
          <el-button link @click="getOrgList">
            <el-icon style="font-size: 20px;">
              <Refresh />
            </el-icon>
          </el-button>
          <el-button style="color: #000000;" link @click="addDepart" v-if="getBtnPermission('btn:addDepart')">
            <el-icon style="font-size: 20px;">
              <Plus />
            </el-icon>
          </el-button>
        </div>
      </div>
      <div class="depart-content" v-loading="treeLoading">
        <el-tree
          accordion
          class="tree"
          ref="departTreeRef"
          :data="treeData"
          :props="defaultProps"
          highlight-current
          :current-node-key="currentKey"
          :expand-on-click-node="false"
          :default-expanded-keys="defaultExpandKeys"
          node-key="id"
          @node-click="handleNodeClick"
          render-after-expand
        >
          <template #default="{ node, data }">
            <span class="custom-tree-node">
              <el-tooltip class="item" effect="dark" placement="top" :content="node.label" :disabled="isShowTooltip">
                <span @mouseover="mouseOver($event)" class="curP custom-tree-label">{{ node.label }}</span>
              </el-tooltip>

              <span class="custom-tree-icon">
                <el-icon style="margin-right: 6px;" @click="addChildDepart(data)" v-if="getBtnPermission('btn:addDepart')">
                  <Plus />
                </el-icon>
                <el-icon style="margin-right: 6px;" @click="editDepart(data)" v-if="getBtnPermission('btn:editDepart')">
                  <EditPen />
                </el-icon>
                <el-icon @click="deleteDepart(data)" v-if="getBtnPermission('btn:deleteDepart')">
                  <Delete />
                </el-icon>
              </span>
            </span>
          </template>
        </el-tree>
      </div>
    </div>

    <!-- 添加、编辑组织 -->
    <el-dialog title="组织管理" v-model="dialogDepartVisible" draggable @close="cancelDepart">
      <el-form
        ref="orgFormRef"
        :model="orgForm"
        label-width="120px"
        class="demo-ruleForm"
        status-icon
        :rules="orgRules"
      >
        <el-form-item label="组织名称" prop="orgName">
          <el-input v-model="orgForm.orgName" placeholder="请输入组织名称"></el-input>
        </el-form-item>
        <el-form-item label="经度" prop="longitude">
          <el-input v-model="orgForm.longitude" placeholder="请输入组织所属地理位置经度"></el-input>
        </el-form-item>
        <el-form-item label="纬度" prop="latitude">
          <el-input v-model="orgForm.latitude" placeholder="请输入组织所属地理位置纬度"></el-input>
        </el-form-item>
        <el-form-item label="区名" prop="region">
          <el-input v-model="orgForm.region" placeholder="请输入组织所属区域"></el-input>
        </el-form-item>
        <el-form-item label="英文名称" prop="enName">
          <el-input v-model="orgForm.enName" placeholder="请输入英文名称"></el-input>
        </el-form-item>
        <el-form-item label="全称" prop="fullName">
          <el-input v-model="orgForm.fullName" placeholder="请输入全称"></el-input>
        </el-form-item>
        <el-form-item label="组织负责人姓名" prop="orgManger">
          <el-input v-model="orgForm.orgManger" placeholder="请输入组织负责人姓名"></el-input>
        </el-form-item>
        <el-form-item label="组织负责人工号" prop="orgMangeraCode">
          <el-input v-model="orgForm.orgMangeraCode" placeholder="请输入组织负责人工号"></el-input>
        </el-form-item>
        <el-form-item label="上级单位" prop="parentId">
          <el-cascader :options="treeData" v-model="orgForm.parentId" :show-all-levels="false" style="width: 100%;" :props="cascaderProps" :disabled="cascaderDisabled"/>
        </el-form-item>
      </el-form>

      <div class="dialog-button">
        <el-button @click="cancelDepart" :loading="departButtonLoading">取消</el-button>
        <el-button type="primary"  @click="submitDepart" :loading="departButtonLoading">确认</el-button>
      </div>
    </el-dialog>

    <!-- 成员列表 -->
    <div class="depart-member">
      <div class="member-search">
        <div class="member-title">成员列表（所属组织：{{ currentDepart.text }}）</div>
        <div class="member-oprea">
          <el-button type="primary" style="margin-right: 10px;" @click="addMember" v-if="getBtnPermission('btn:addUserByDepart')">
            <template #icon>
              <img src="../../assets/images/add_member.png" alt="">
            </template>
            新建成员
          </el-button>

          <el-form @submit.native.prevent="() => getOrgUsers">
            <el-form-item>
              <el-input v-model="formInline.name" placeholder="请输入成员姓名" @keyup.enter="getOrgUsers">
                <template #suffix>
                  <el-icon class="el-input__icon curP"  @click="getOrgUsers"><Search /></el-icon>
                </template>
              </el-input>
            </el-form-item>
          </el-form>
        </div>
      </div>
      
      <div class="table-data" v-loading="loading" style="margin-top: 30px;">
        <el-table
          :data="departMemberData"
          stripe
          borderresizable
          highlight-hover-row
          show-overflow
          keep-source
        >
          <el-table-column
            v-for="(tableItem, tableIndex) in departMemberTableColumns" :key="tableIndex"
            :prop="tableItem.field"
            :label="tableItem.label"
            :min-width="tableItem.minWidth"
            :formatter="tableItem.formatter"
          ></el-table-column>
          <el-table-column
            fixed="right"
            field="opera"
            label="操作"
            min-width="100"
          >
            <template #default="{ row }">
              <el-button
                style="color: #5897DB;"
                link
                @click="memberDetail(row)"
              >查看</el-button>
              <span v-if="getBtnPermission('btn:deleteUserByDepart')">  |  </span>
              <el-button
                style="color: #5897DB;"
                link
                @click="memberDelete(row)"
                v-if="getBtnPermission('btn:deleteUserByDepart')"
              >移除</el-button>
            </template>
          </el-table-column>
        </el-table>

        <!-- <div class="table-page">
          <el-pagination background layout="prev, pager, next" :total="dataTotal" :page-size="pageSize" :current-page="currentPage" @current-change="currentChange" />
        </div> -->
      </div>
    </div>

    <!-- 新增成员 -->
    <el-dialog title="新增成员" v-model="dialogMemberVisible" draggable @close="cancelMember">
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        label-width="100px"
        class="demo-ruleForm"
        status-icon
        :rules="rules"
      >
        <el-form-item label="选择用户" prop="userIds">
          <el-select
            v-model="ruleForm.userIds"
            placeholder="请选择用户"
            clearable
            multiple
            filterable
            style="width: 100%;"
          >
            <el-option v-for="(item, index) in userList" :key="index" :label="item.name" :value="item.id" />
          </el-select>
        </el-form-item>
      </el-form>
      <div class="dialog-button">
        <el-button @click="cancelMember" :loading="memberButtonLoading">取消</el-button>
        <el-button type="primary" @click="submitMember" :loading="memberButtonLoading">新增</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
export default{ name: 'backendSystemDepart' }
</script>

<script setup>
import { ref, reactive, onMounted, nextTick } from 'vue';
import { useRouter } from 'vue-router'
import { Search, Plus, EditPen, Refresh, Delete } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { http } from '@/utils/http/index';
import { arrayToTree, findLevel } from "@/utils/index.js"
import { useAuthStore } from '@/stores/modules/auth.js';

/* 路由 */
const router = useRouter()

const authStore = useAuthStore()

/* 所有按钮权限 */
const btnPermissionList = ref([])
btnPermissionList.value = authStore.base_auth_tree.find(item => item.controlName == 'btn_permission')?.children

/* 查询是否有权限 */
const getBtnPermission = (name) => {
  let flag = false
  if( btnPermissionList.value.find(item => item.controlName == name && item.selected == 1) ) {
    flag = true
  }
  return flag
}

onMounted(() => {
  getOrgList()
})

/* 树数据 */
const treeData = ref([])
const departTreeRef = ref(null)

/* 树配置 */
const defaultProps = ref({
  children: 'children',
  label: 'text',
})

/* 当前查看的组织 */
const currentDepart = ref({})

/* 当前查看的组织id */
const currentKey = ref("")
const defaultExpandKeys = ref([])

/* 点击某一树节点 */
const handleNodeClick = (data) => {
  currentDepart.value = data
  formInline.value.name = ""
  getOrgUsers()
}

/* 树加载 */
const treeLoading = ref(false)

/* 获取组织树列表 */
const getOrgList = () => {
  treeLoading.value = true
  defaultExpandKeys.value = []
  http.$GET("/OrgManager/GetUserOrgInfo", { userId: authStore.base_auth_userinfo?.id }).then(res => {
    treeLoading.value = false
    if(res.isError) return ElMessage.warning(res.message)
    if( !res.Result.data.length ) return

    treeData.value = arrayToTree(res.Result.data)
    currentDepart.value = treeData.value[0]
    getOrgUsers()

    currentKey.value = treeData.value[0].id
    defaultExpandKeys.value.push(currentKey.value)

    /* 默认选中树节点 */
    nextTick(() => {
      departTreeRef.value.setCurrentKey(currentKey.value)
    })
  }).catch(() => {
    treeLoading.value = false
    ElMessage.warning('加载失败')
  })
}

/* 超出宽度的内容显示弹出框 */
const isShowTooltip = ref(null)
const mouseOver = (event) => {
  var target = event.target;
  let textLength = target.clientWidth;
  let containerLength = target.scrollWidth;
  if (textLength < containerLength) {
    isShowTooltip.value = false
  } else {
    isShowTooltip.value = true
  }
}

/* 新增、编辑组织弹窗 */
const dialogDepartVisible = ref(false)
const orgFormRef = ref(null)
const orgForm = ref({
  orgName: "",
  enName: "",
  fullName: "",
  orgManger: "",
  orgMangeraCode: "",
  parentId: "",
  level: "",
  longitude: "",
  latitude: "",
  region: "",
})
const orgRules = reactive({
  orgName: [
    { required: true, message: '请填写组织名称', trigger: 'blur' }
  ],
})

/* 级联选择器配置 */
const cascaderProps = ref({
  label: "text",
  value: "id",
  children: 'children',
  checkStrictly: true,
})

/* 级联选择器禁用 */
const cascaderDisabled = ref(false)

/* 新增、编辑提交按钮禁用 */
const departButtonLoading = ref(false)

/* 点击新建组织 */
const addDepart = () => {
  dialogDepartVisible.value = true
  if(orgForm.value.id) {
    delete orgForm.value.id
  }
}

/* 在已有组织下新建子级组织 */
const addChildDepart = (data) => {
  dialogDepartVisible.value = true
  orgForm.value.parentId = data.id
  cascaderDisabled.value = true
  if(orgForm.value.id) {
    delete orgForm.value.id
  }
}

/* 点击编辑组织 */
const editDepart = (data) => {
  dialogDepartVisible.value = true
  if(data.children.length) {
    cascaderDisabled.value = true
  }
  getOrgDetail(data.id).then(res => {
    Object.keys(orgForm.value).forEach((key)=>{
      if(res.result.content.org[key] != null){
        orgForm.value[key] = res.result.content.org[key];
      }
    })
    orgForm.value.id = res.result.content.org.id
  })
}

/* 取消新增、编辑组织 */
const cancelDepart = () => {
  orgFormRef.value.resetFields()
  orgForm.value.parentId = ""
  dialogDepartVisible.value = false
  cascaderDisabled.value = false
}

/* 提交新增、编辑组织 */
const submitDepart = () => {
  orgFormRef.value.validate((valid, fields) => {
    if(valid) {
      departButtonLoading.value = true
      let params = JSON.parse(JSON.stringify(orgForm.value))

      /* 处理parentId和level字段 */
      if(typeof(params.parentId) == 'object' && params.parentId.length) {
        params.parentId = params.parentId[params.parentId.length - 1]
      }

      if(params.parentId && params.parentId != 'whsw') {
        params.level = findLevel(treeData.value, params.parentId) + 1
      } else {
        params.parentId = "whsw"
        params.level = '1'
      }

      const formData = new FormData()
      for(let k in params) {
        formData.append(k ,params[k])
      }

      http.$POST("/OrgManager/EditOrgDo", formData).then(res => {
        departButtonLoading.value = false
        if(res.isError) return ElMessage.warning(res.message)
        ElMessage.success("操作成功")
        cancelDepart()
        getOrgList()
      }).catch(() => {
        cancelDepart()
        ElMessage.warning("操作失败")
      })
    }else{
      ElMessage.warning("请先完成必填项")
    }
  })
}

/* 查询组织详情方法 */
const getOrgDetail = (id) => {
  return new Promise((resolve) => {
    let params = {
      id: id
    }
    if(formInline.value.name) {
      params.name = formInline.value.name
    }
    http.$GET("/OrgManager/GetOrgById", params).then(res => {
      if(res.isError) return ElMessage.warning(res.message)
      resolve(res)
    })
  })
}

/* 点击删除组织 */
const deleteDepart = (row) => {
  ElMessageBox.confirm(
    `确定将删除此组织吗？`,
    '请确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    let params = {
      orgId: row.id
    }
    const formData = new FormData()
    for(let k in params) {
      formData.append(k ,params[k])
    }
    http.$POST("/OrgManager/RemoveOrg", formData).then(res => {
      if(res.isError) return ElMessage.warning(res.message)
      ElMessage.success("操作成功")
      getOrgList()
    }).catch(() => {
      ElMessage.warning("操作失败")
    })
  }).catch(() => {
    ElMessage.info("取消删除")
  })
}

/* 搜索成员表单 */
const formInline = ref({
  name: "",
})

/* 成员列表分页 */
const dataTotal = ref(0)
const pageSize = ref(10)
const currentPage = ref(1)

/* 切换页码方法 */
const currentChange = (val) => {
  currentPage.value = val
  getOrgUsers()
}

/* 表格数据加载动画 */
const loading = ref(false)

/* 表格数据 */
const departMemberData = ref([])

/* 状态字段过滤 */
const statusFormatter = (row, column, cellValue) => {
  return cellValue == "1" ? "正常" : "停用"
}

/* 表格字段 */
const departMemberTableColumns = reactive([
  { field: "name", label: "姓名", minWidth: "120" },
  { field: "loginName", label: "账号", minWidth: "120" },
  { field: "email", label: "邮箱", minWidth: "140" },
  { field: "status", label: "状态", minWidth: "120", formatter: statusFormatter },
])

/* 点击搜索用户 */
const getOrgUsers = () => {
  getOrgDetail(currentDepart.value.id).then(res => {
    departMemberData.value = res.result.content.users
  })
}

/* 新增成员弹窗 */
const dialogMemberVisible = ref(false)
const ruleFormRef = ref(null)
const ruleForm = ref({
  userIds: []
})
const rules = reactive({
  userIds: [
    { required: true, message: '请选择用户', trigger: 'change' }
  ],
})
const userList = ref([])

/* 获取用户列表 */
const getUserList = () => {
  let params = {
    orgId: currentDepart.value.id,
  }
  http.$GET("UserManager/GetUserListByNoOrg", params).then(res => {
    if (res.isError) return ElMessage.warning(res.message)
    userList.value = userList.value.concat(res.result.content)
  }).catch(() => {
    ElMessage.warning("查询用户列表失败")
  })
}

/* 点击新增成员 */
const addMember = () => {
  dialogMemberVisible.value = true
  getUserList()
}

/* 新增按钮禁用 */
const memberButtonLoading = ref(false)

/* 新增成员提交 */
const submitMember = () => {
  ruleFormRef.value.validate((valid, fields) => {
    if(valid) {
      memberButtonLoading.value = true

      let userIds = JSON.parse(JSON.stringify(ruleForm.value.userIds))
      let params = {
        orgId: currentDepart.value.id,
        userIds: userIds.length ? userIds.join(",") : ''
      }

      const formData = new FormData()
      for(let k in params) {
        formData.append(k ,params[k])
      }

      http.$POST("/OrgManager/AddUserToOrg", formData).then(res => {
        memberButtonLoading.value = false
        if(res.isError) return ElMessage.warning(res.message)
        ElMessage.success("操作成功")
        cancelMember()
        getOrgUsers()
      }).catch(() => {
        memberButtonLoading.value = false
        ElMessage.warning("操作失败")
      })
    }else{
      ElMessage.warning("请先完成必填项")
    }
  })
}

/* 取消新增成员 */
const cancelMember = () => {
  dialogMemberVisible.value = false
  ruleFormRef.value.resetFields()
  userList.value = []
}

/* 点击查看成员详情 */
const memberDetail = (row) => {
  let { href } = router.resolve({
    path: "/UserManager/UserDetail",
    query: { id: row.id }
  })
  window.open(href, "_blank")
}

/* 点击移除成员 */
const memberDelete = (row) => {
  ElMessageBox.confirm(
    `确定将此用户从组织  ${currentDepart.value.text}  中移除吗？`,
    '请确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    let params = {
      orgId: currentDepart.value.id,
      userIds: row.id
    }
    const formData = new FormData()
    for(let k in params) {
      formData.append(k ,params[k])
    }

    http.$POST("/OrgManager/RemoveUserToOrg", formData).then(res => {
      if(res.isError) return ElMessage.warning(res.message)
      ElMessage.success("操作成功")
      getOrgUsers()
    })
  }).catch(() => {
    ElMessage.info("已取消移除")
  })
}
</script>

<style lang='scss' scoped>
@import "@/assets/styles/backendElement.scss";
.depart-page{
  display: flex;
  height: 100%;
  .depart-tree{
    min-width: 360px;
    background: #fff;
    margin-right: 20px;
    height: 100%;
  }
  .depart-member{
    width: calc(100% - 380px);
    background: #fff;
    height: 100%;
  }
  .depart-title{
    height: 59px;
    display: flex;
    background: #FAFAFA;
    font-size: 18px;
    color: #000000;
    align-items: center;
    justify-content: space-between;
    padding: 17px 13px 17px 27px;
    font-weight: bold;
    img{
      width: 19px;
      height: 20px;
    }
  }
  .depart-content{
    padding: 14px;
    height: calc(100vh - 186px);
    overflow: auto;
  }
  .custom-tree-icon{
    :deep(.el-icon) {
      font-size: 16px;
    }
  }
}

/* 成员模块 */
.depart-member{
  padding: 18px 20px;
  .member-search{
    display: flex;
    justify-content: space-between;
    :deep(.el-input__suffix .el-icon) {
      font-size: 20px;
      font-weight: bold;
      color: var(--theme-color);
    }
  }
  .member-title{
    font-size: 18px;
    font-weight: bold;
    padding-left: 8px;
  }
  .member-oprea{
    display: flex;
  }
}
</style>